/**
 * Copyright (c) 2015-2016, Chill Zhuang 庄骞 (smallchill@163.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.john.springboot.controller;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import org.springframework.util.StringUtils;

public class DateUtil {
	private final static SimpleDateFormat sdfYear = new SimpleDateFormat("yyyy");

	private final static SimpleDateFormat sdfDay = new SimpleDateFormat("yyyy-MM-dd");

	private final static SimpleDateFormat sdfDays = new SimpleDateFormat("yyyyMMdd");
	
	private final static SimpleDateFormat sdfMoth = new SimpleDateFormat("yyyyMM");
	
	private final static SimpleDateFormat sdfTimes = new SimpleDateFormat("HHmmss");

	private final static SimpleDateFormat sdfTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	
	private final static SimpleDateFormat sdfmsTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
	
	private final static SimpleDateFormat allTime = new SimpleDateFormat("yyyyMMddHHmmss");

	public final static SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd");
	
	public final static SimpleDateFormat sdfDateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");	

	public final static String YYYY_MM_DD = "yyyy-MM-dd";
	public final static String YYYYMMDD = "yyyy/MM/dd";
	public final static String YYYY_MM = "yyyy-MM";
	public final static String YYYY = "yyyy";
	public final static String HH_MM_SS = "HH:mm:ss";
	public final static String YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";
	public final static String HH_MM = "HH:mm";
	public final static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";	
	public final static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

	/**
	 * 获取YYYY格式
	 * 
	 * @return
	 */
	public static String getYear() {
		return sdfYear.format(new Date());
	}

	/**
	 * 获取YYYY格式
	 * 
	 * @return
	 */
	public static String getYear(Date date) {
		return sdfYear.format(date);
	}

	/**
	 * 获取YYYY-MM-DD格式
	 * 
	 * @return
	 */
	public static String getDay() {
		return sdfDay.format(new Date());
	}

	/**
	 * 获取YYYY-MM-DD格式
	 * 
	 * @return
	 */
	public static String getDay(Date date) {
		return sdfDay.format(date);
	}

	/**
	 * 获取YYYYMMDD格式
	 * 
	 * @return
	 */
	public static String getDays() {
		return sdfDays.format(new Date());
	}
	
	/**
	 * 获取YYYYMM格式
	 * @return
	 */
	public static String getMoth(Date date) {
		return sdfMoth.format(date);
	}

	/**
	 * 获取YYYYMMDD格式
	 * 
	 * @return
	 */
	public static String getDays(Date date) {
		return sdfDays.format(date);
	}
	
	/**
	 * 获取HHMMSS格式
	 * 
	 * @return
	 */
	public static String getTimes() {
		return sdfTimes.format(new Date());
	}

	/**
	 * 获取HHMMSS格式
	 * 
	 * @return
	 */
	public static String getTimes(Date date) {
		return sdfTimes.format(date);
	}

	/**
	 * 获取YYYY-MM-DD HH:mm:ss格式
	 * 
	 * @return
	 */
	public static String getTime() {
		return sdfTime.format(new Date());
	}
	
	/**
	 * 获取YYYY-MM-DD HH:mm:ss.SSS格式
	 * 
	 * @return
	 */
	public static String getMsTime() {
		return sdfmsTime.format(new Date());
	}
	
	/**
	 * 获取YYYYMMDDHHmmss格式
	 * 
	 * @return
	 */
	public static String getAllTime() {
		return allTime.format(new Date());
	}

	/**
	 * 根据YYYYMMDDHHmmss格式时间字符串获取日期
	 * @param dateAndTime
	 * @return
	 */
	public static Date getAllTime(String dateAndTime) {
		try{
			return allTime.parse(dateAndTime);
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 获取YYYY-MM-DD HH:mm:ss格式
	 * 
	 * @return
	 */
	public static String getTime(Date date) {
		return sdfTime.format(date);
	}

	/**
	 * @Title: compareDate
	 * @Description:(日期比较，如果s>=e 返回true 否则返回false)
	 * @param s
	 * @param e
	 * @return boolean
	 * @throws
	 * @author luguosui
	 */
	public static boolean compareDate(String s, String e) {
		if (parseDate(s) == null || parseDate(e) == null) {
			return false;
		}
		return parseDate(s).getTime() >= parseDate(e).getTime();
	}
	
	/**
	 * 时间比较
	 * @Title: compareDate 
	 * @Description: TODO(这里用一句话描述这个方法的作用) 
	 * @param s
	 * @param e
	 * @param pattern
	 * @date 2017-12-28 16:51 
	 * @author QIPE001
	 * @updateDate 2017-12-28 16:51
	 * @updateAuthor QIPE001
	 * @version V1.0 
	 * @return boolean 
	 * @throws
	 */
	public static boolean compareDate(String s, String e,String pattern) {
		if (parseDate(s,pattern) == null || parseDate(e,pattern) == null) {
			return false;
		}
		return parseDate(s,pattern).getTime() >= parseDate(e,pattern).getTime();
	}
	
	public static Date parseDateQp(String date,String pattern) {
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(pattern);
			return sdf.parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 格式化日期
	 * 
	 * @return
	 */
	public static Date parseDate(String date) {
		try {
			return sdfDay.parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 格式化日期
	 * 
	 * @return
	 */
	public static Date parseTime(String date) {
		try {
			return sdfTime.parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 格式化日期
	 * 
	 * @return
	 */
	public static Date parse(String date, String pattern) {
		DateFormat fmt = new SimpleDateFormat(pattern);
		try {
			return fmt.parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 格式化日期
	 * 
	 * @return
	 */
	public static String format(Date date, String pattern) {
		if(date==null){
			return ""; 
		}
		DateFormat fmt = new SimpleDateFormat(pattern);
		return fmt.format(date);
	}
	
	/**
	 * 格式化字符串日期格式
	 * @param date yyyyMMdd 格式
	 * @return
	 */
	public static String formatStrToDate(String date) {
	    if (StringUtils.isEmpty(date)) {
	        return null;
	    }
	    try {
            Date fmtDate = sdfDays.parse(date);
            return sdfDay.format(fmtDate);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
	}
	
	/**
	 * 把日期转换为Timestamp
	 * 
	 * @param date
	 * @return
	 */
	public static Timestamp format(Date date) {
		return new Timestamp(date.getTime());
	}

	/**
	 * 校验日期是否合法
	 *
	 * @return
	 */
	public static boolean isValidDate(String s) {
		try {
			sdfTime.parse(s);
			return true;
		} catch (Exception e) {
			// 如果throw java.text.ParseException或者NullPointerException，就说明格式不对
			return false;
		}
	}

	/**
	 * 校验日期是否合法
	 *
	 * @return
	 */
	public static boolean isValidDate(String s, String pattern) {
		DateFormat fmt = new SimpleDateFormat(pattern);
		try {
			fmt.parse(s);
			return true;
		} catch (Exception e) {
			// 如果throw java.text.ParseException或者NullPointerException，就说明格式不对
			return false;
		}
	}

	public static int getDiffYear(String startTime, String endTime) {
		DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
		try {
			int years = (int) (((fmt.parse(endTime).getTime() - fmt.parse(
					startTime).getTime()) / (1000 * 60 * 60 * 24)) / 365);
			return years;
		} catch (Exception e) {
			// 如果throw java.text.ParseException或者NullPointerException，就说明格式不对
			return 0;
		}
	}

	/**
	 * <li>功能描述：时间相减得到天数
	 *
	 * @param beginDateStr
	 * @param endDateStr
	 * @return long
	 * @author Administrator
	 */
	public static long getDaySub(String beginDateStr, String endDateStr) {
		long day = 0;
		SimpleDateFormat format = new SimpleDateFormat(
				"yyyy-MM-dd");
		Date beginDate = null;
		Date endDate = null;

		try {
			beginDate = format.parse(beginDateStr);
			endDate = format.parse(endDateStr);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		day = getDaySub(endDate,beginDate);
		// System.out.println("相隔的天数="+day);

		return day;
	}
	
	public static long getDaySub(Date beginDate,Date endDate) {
		long day=(endDate.getTime()-beginDate.getTime())/(24*60*60*1000);
		//System.out.println((endDate.getTime()-beginDate.getTime()));
		//System.out.println((endDate.getTime()-beginDate.getTime())%(24*60*60*1000));
		/*System.out.println(((((endDate.getTime()-beginDate.getTime())%(24*60*60*1000))%(60*60*1000))%(60*1000))/1000);
		System.out.println((((endDate.getTime()-beginDate.getTime())%(24*60*60*1000))%(60*60*1000))/(60*1000));
		System.out.println(((endDate.getTime()-beginDate.getTime())%(24*60*60*1000))/(60*60*1000));*/
		return day;
	}

	/**
	 * 得到n天之后的日期
	 * 
	 * @param days
	 * @return
	 */
	public static String getAfterDayDate(String days) {
		int daysInt = Integer.parseInt(days);

		Calendar canlendar = Calendar.getInstance(); // java.util包
		canlendar.add(Calendar.DATE, daysInt); // 日期减 如果不够减会将月变动
		Date date = canlendar.getTime();

		SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateStr = sdfd.format(date);

		return dateStr;
	}

	/**
	 * 得到n天之后是周几
	 * 
	 * @param days
	 * @return
	 */
	public static String getAfterDayWeek(String days) {
		int daysInt = Integer.parseInt(days);

		Calendar canlendar = Calendar.getInstance(); // java.util包
		canlendar.add(Calendar.DATE, daysInt); // 日期减 如果不够减会将月变动
		Date date = canlendar.getTime();

		SimpleDateFormat sdf = new SimpleDateFormat("E");
		String dateStr = sdf.format(date);

		return dateStr;
	}

	public static String getDateFormat(){
		return sdfDate.format(new Date());
	}
	
	public static String getDateTimeFormat(){
		return sdfDateTime.format(new Date());
	}
	
	public static String getTomorrowDateFormat(){
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH)+1);
		return sdfDate.format(calendar.getTime());
	}
	
	public static String getFullDateTimeFormat(){
		return Format(new Date(),YYYYMMDDHHMMSS);
	}
	
	public static String Format(Date date, String pattern) {
		return new SimpleDateFormat(pattern).format(date);
	}
	
	/** 以给定格式返回date类型 */
	public static Date getDate(String format, String date) {
		try {
			return new SimpleDateFormat(format).parse(date);
		} catch (Exception e) {
			return null;
		}
	}
	
	 public static Date getDateBefore(Date d, int day) {      
         Calendar now = Calendar.getInstance();      
         now.setTime(d);      
         now.set(Calendar.DATE, now.get(Calendar.DATE) - day);      
         return now.getTime();      
     }     
       
     public static Date getDateAfter(Date d, int day) {      
        Calendar now = Calendar.getInstance();      
         now.setTime(d);      
        now.set(Calendar.DATE, now.get(Calendar.DATE) + day);      
         return now.getTime();      
     } 
	 /**
     * 返回一个时间集合
     */
    public static List<Date> getDateList(Date startDate, Date endDate) {
		ArrayList<Date> dates=new ArrayList<Date>();
	    dates.add(startDate);
	    if(startDate.compareTo(endDate)==0){
	    	return dates;
	    }
		if(getDateAfter(startDate, 1).compareTo(endDate)==0){
			dates.add(endDate);
			return dates;
		}
		Date date=startDate;
		boolean flag=true;
		while(flag){
			date = getDateAfter(date, 1);
			if(endDate.compareTo(date)==0){
				dates.add(endDate);
				flag=false;
				continue;
			}
			dates.add(date);
		}
		return dates;
	}
	
	public static int getMonth(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.MONTH)+1;
	}
     
	 //得到小时
     public static int getHour(Date date) {
          Calendar calendar = Calendar.getInstance();
          calendar.setTime(date);
          return calendar.get(Calendar.HOUR_OF_DAY);
      }

      //得到分钟
      public static int getMinute(Date date) {
          Calendar calendar = Calendar.getInstance();
          calendar.setTime(date);
          return calendar.get(Calendar.MINUTE);
      }

      //设置小时
      public static Date setHour(int hour, Date date) {
          Calendar calendar = Calendar.getInstance();
          calendar.setTime(date);
          calendar.set(Calendar.HOUR_OF_DAY, hour);
          return calendar.getTime();
      }

      //设置分钟
      public static Date setMinute(int minute, Date date) {
          Calendar calendar = Calendar.getInstance();
          calendar.setTime(date);
          calendar.set(Calendar.MINUTE, minute);
          return calendar.getTime();
      }
      public  static Date parseDate(String datestr,String formate){
		if (formate==null){
			formate="yyyy-MM-dd HH:mm:ss";

		}
		  SimpleDateFormat sdf= new SimpleDateFormat(formate);

		  Date date;
		  try{
			  date=sdf.parse(datestr);
			  return date;
		  }catch(Exception e){
			  System.out.println(e.getMessage());
		  }
		  return  null;

      }
      
	public static void main(String[] args) {
		System.err.println(compareDate(getTime(new Date()),"2017-12-25 17:00:00","yyyy-MM-dd HH:mm:ss"));
	}
	
	private static Map dateFormats=new Hashtable();
	private static DateFormat getDateFormat(String pattern){
		if(!dateFormats.containsKey(pattern)){
			DateFormat df = new SimpleDateFormat(pattern);
			dateFormats.put(pattern, df);
		}
		return (DateFormat)dateFormats.get(pattern); 
	}
	  	
	  	
	public static String getDispDate(String strDate,String srcPattern,String dstPattern) {
		DateFormat srcDf = getDateFormat(srcPattern);
		DateFormat dstDf = getDateFormat(dstPattern);
		try {
			return dstDf.format(srcDf.parse(strDate));
		} catch (ParseException e) {
		}
		return "";
	}
	
	/**
	 * 时间加减分钟数
	 * @param date
	 * @param min
	 * @return
	 */
	public static Date getDateMin(Date date,int min){
		Calendar canlendar = Calendar.getInstance(); // java.util包 
		canlendar.setTime(date);
		canlendar.add(Calendar.MINUTE, min);
        return canlendar.getTime();
	}
	
	/**
	 * 时间加减小时数
	 * @param date
	 * @param hour
	 * @return
	 */
	public static Date getDateHour(Date date,int hour){
		Calendar canlendar = Calendar.getInstance(); // java.util包 
		canlendar.setTime(date);
		canlendar.add(Calendar.HOUR_OF_DAY, hour);
        return canlendar.getTime();
	}
	
	public static Date getDateMonth(Date d, int month) {      
        Calendar now = Calendar.getInstance();      
        now.setTime(d); 
        now.add(Calendar.MONTH, month);
        return now.getTime();      
    }
	
	/**
	 * 相差月份
	 * @Title: getMonthSpace 
	 * @Description: TODO(这里用一句话描述这个方法的作用) 
	 * @param date1
	 * @param date2
	 * @date 2017-12-28 16:49 
	 * @author QIPE001
	 * @updateDate 2017-12-28 16:49
	 * @updateAuthor QIPE001
	 * @version V1.0 
	 * @return int 
	 * @throws
	 */
	public static int getMonthSpace(String date1, String date2) {
        int result = 0;
        int month = 0;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        try {
			c1.setTime(sdf.parse(date1));
			c2.setTime(sdf.parse(date2));
			result = c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH);
			month = (c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR)) * 12;
			
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        return month + result;
    }

	/**
	 * 获取指定分钟之前的时间
	 * @param minute 指定分钟
	 * @return 指定分钟之前格式化后的时间 yyyy-MM-dd HH:MM
	 */
	public static String getDateOfSpecifyMinuteBeFore(Long minute) {
		LocalDateTime today = LocalDateTime.now();
		LocalDateTime after = today.minus(minute, ChronoUnit.MINUTES);
		return DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").format(after);
	}
}
